
#include "tensorflow/lite/core/interpreter.h"
#include "tensorflow/lite/delegates/gpu/api.h"
#include "tensorflow/lite/delegates/gpu/cl/api.h"
#include "tensorflow/lite/delegates/gpu/common/model_builder.h"
// #include "tensorflow/lite/interpreter.h"
#include <memory>

#include "tensorflow/lite/builtin_ops.h"
#include "tensorflow/lite/create_op_resolver.h"
#include "tensorflow/lite/interpreter_builder.h"
#include "tensorflow/lite/model_builder.h"
#include "tensorflow/lite/op_resolver.h"

using namespace std;
using namespace tflite;
using namespace tflite::gpu;
using namespace tflite::gpu::cl;

int main(int argc, char* argv[]) {
  InferenceEnvironmentOptions options;
  unique_ptr<InferenceEnvironment> env;

  if (!NewInferenceEnvironment(options, &env, nullptr).ok()) {
    return -1;
  }

  auto model = FlatBufferModel::BuildFromFile("fakemodel.tflite");
  auto opResolver = CreateOpResolver();
  GraphFloat32 gpuModel;

  if (!gpu::BuildFromFlatBuffer(*model, *opResolver, &gpuModel).ok()) {
    return -1;
  }

  cl::InferenceOptions inferenceOptions;
  unique_ptr<gpu::InferenceBuilder> builder;
  if (!env->NewInferenceBuilder(inferenceOptions,
                                std::move(gpuModel), &builder)
           .ok()) {
    return -1;
  }

  ObjectDef glTexDef;
  glTexDef.data_layout = DataLayout::DHWC4;
  glTexDef.data_type = DataType::FLOAT16;
  glTexDef.object_type = ObjectType::OPENGL_TEXTURE;

  if (!builder->SetInputObjectDef(0, glTexDef).ok()) {
    return -1;
  }

  if (!builder->SetOutputObjectDef(0, glTexDef).ok()) {
    return -1;
  }

  unique_ptr<InferenceRunner> runner;
  if (!builder->Build(&runner).ok()) {
    return -1;
  }

  if (!runner->SetInputObject(0, OpenGlBuffer(0)).ok()) {
    return -1;
  }

  if (!runner->SetOutputObject(0, OpenGlBuffer(0)).ok()) {
    return -1;
  }

  if (!runner->Run().ok()) {
    return -1;
  }
}